﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;

namespace TableTop.DataModel
{
    /// <summary>
    /// This class will do a magicabula for serialize and deserialize generic DataContracts
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [DataContract(Namespace = "http://www.tabletop.net/DataModel")]
    public class TransportableSerializer<T>
    {
        [DataMember]
        private string strDataXML;
        [DataMember]
        private String strFullAssemblyName;
        [DataMember]
        private String strFullTypeName;

        public String AssemblyName
        {
            get
            {
                return this.strFullAssemblyName;
            }
            private set
            {
                this.strFullAssemblyName = value;
            }
        }

        public String TypeName
        {
            get
            {
                return this.strFullTypeName;
            }
            private set 
            { 
                this.strFullTypeName = value; 
            }
        }

        public String DataXML
        {
            get
            {
                return this.strDataXML;
            }

            private set
            {
                this.strDataXML = value;
            }
        }

        public T Deserialize()
        {
            Type tpCurrentSheetType = null;
            DataContractSerializer dcsSerializer = null;
            XmlReader xmlReader = null;
            StringReader srStringReader = null;
            T icsCurrentSheet = default(T);
            
            srStringReader = new System.IO.StringReader(this.strDataXML);
            xmlReader = new XmlTextReader(srStringReader);

            tpCurrentSheetType = Type.GetType(this.strFullTypeName, true);
            dcsSerializer = new DataContractSerializer(tpCurrentSheetType);
            icsCurrentSheet = (T) dcsSerializer.ReadObject(xmlReader);
            return icsCurrentSheet;
        }

        public void Serialize(T ObjectData)
        {
            Type tpCurrentSheetType = null;
            DataContractSerializer dcsSerializer = null;
            XmlWriter xmlWriter = null;
            StringBuilder sbXmlBuilder = null;
            System.IO.StringWriter srStringWriter  = null;

            tpCurrentSheetType = ObjectData.GetType();
            sbXmlBuilder = new StringBuilder();
            srStringWriter = new System.IO.StringWriter(sbXmlBuilder);
            xmlWriter = new XmlTextWriter(srStringWriter);
            dcsSerializer = new DataContractSerializer(tpCurrentSheetType);
            dcsSerializer.WriteObject(xmlWriter, ObjectData);

            this.strDataXML = sbXmlBuilder.ToString();
            this.strFullTypeName = tpCurrentSheetType.AssemblyQualifiedName;
            this.strFullAssemblyName = tpCurrentSheetType.Assembly.FullName;
        }

        public TransportableSerializer(T ObjectData)
        {
            this.Serialize(ObjectData);
        }

        public TransportableSerializer()
        {
        }
    }
}
